﻿using Authentication.Configuration;
using Authentication.Model.Model;
using Authentication.Web.Service.Core;
using Common.Util;
using Common.Contract;
using Common.Contract.Authentication;
using Common.Contract.Authentication.Record;
using Common.Contract.Authentication.Request;
using Common.Contract.Authentication.Response;
using Common.Contract.Paging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Authentication.ServiceCommand;
using Common.Contract.Authentication.Identifier;

namespace Authentication.Web.Service
{
    public class AuthenticationService : ServiceBase, IAuthentication
    {
        public ResponseRecord CheckLogin(UserRecord userRecord, HttpRequestBase Request = null)
        {
            ResponseRecord result = ResponseRecord.Default;
            if (userRecord == null)
            {
                result.IsSuccess = false;
                result.ErrorMessage = "User record to check is null";
                return result;
            }
            var isSupperAdmin = (userRecord.UserName.ToUpper() == SystemConfiguration.SUPPER_ADMIN.ToUpper());
            RetrieveUserByUserNameRequest request = new RetrieveUserByUserNameRequest
            {
                Header = new RequestHeaderRecord { ApplicationKey = userRecord.ApplicationKey, CallerName = "Authentication.Web.Service.AuthenticationService.CheckLogin" },
                UserName = userRecord.UserName
            };
            var response = RetrieveUserByUserName(request);

            //false when not Admin and not retrieve user recode
            if (!response.IsSuccess && !isSupperAdmin)
            {
                result.ErrorMessage = response.ErrorMessage;
                result.IsSuccess = response.IsSuccess;
                return result;
            }
            else
            {
                bool loginStatus = response.IsSuccess;
                var userLogIn = response.Record;
                if (userLogIn == null && !isSupperAdmin)
                {
                    result.IsSuccess = false;
                    result.ErrorMessage = @"The user name or password provided is incorrect";
                    return result;
                }

                // so sánh mật khẩu
                bool isAccessAuth = false;
                if (!isSupperAdmin)//Normal user in database
                {
                    string salt = userLogIn.Password;
                    isAccessAuth = (userLogIn.Active && salt == userRecord.Password.ToSHAPassword());
                }
                else //Sysadmin user config
                {
                    if (userLogIn == null)
                    {
                        //Insert supper admin record to db
                        RegisterUserRequest addUser = new RegisterUserRequest
                        {
                            Header = request.Header,
                            Record = new UserRecord
                            {
                                ApplicationKey = userRecord.ApplicationKey,
                                Email = userRecord.Email,
                                GroupIdentifier = null,
                                Password = "e03f4663da577be11bf0e00262b6e7396c70955690959877f39388d7a51541e8",
                                UserName = SystemConfiguration.SUPPER_ADMIN
                            }
                        };

                        var registerResponse = RegisterUser(addUser);
                        if (registerResponse.IsSuccess)
                        {
                            userLogIn = addUser.Record;
                        }
                    }
                    string salt = userLogIn.Password;
                    isAccessAuth = (salt == userRecord.Password.ToSHAPassword());
                }

                if (!isAccessAuth)
                {
                    result.IsSuccess = false;
                    result.ErrorMessage = @"The user name or password provided is incorrect";
                    return result;
                }


                // Don log with sysadmin
                if (Request != null && !isSupperAdmin)
                {
                    var ClientIPAddress = Request.UserHostAddress;
                    var ClientLogonUser = Request.LogonUserIdentity.Name;
                    var ComClientName = Request.UserHostName;
                    var LocalSystemUser = userLogIn.UserName;
                    var LocalSystemFullName = userLogIn.UserName;
                    var maxId = Provider.Users.GetMaxAccountLogonAuditID(userRecord.ApplicationKey, LocalSystemUser);
                    var userLogonAudit = new AccountLogonAudit
                    {
                        ApplicationKey = userRecord.ApplicationKey.ToString(),
                        Id = maxId + 1,
                        FullnameEnglish = LocalSystemFullName,
                        UserName = LocalSystemUser,
                        CreationDate = DateTime.Now,
                        ClientUserName = ClientLogonUser,
                        ClientMachineName = ComClientName,
                        ClientIpAddress = ClientIPAddress
                    };
                    Provider.Users.AddAccountLogonAudit(userLogonAudit);
                }
            }
            return result;
        }

        public RetrieveUserResponse RetrieveUserByUserName(RetrieveUserByUserNameRequest request)
        {
            RetrieveUserResponse response = new RetrieveUserResponse { IsSuccess = true, ErrorMessage = "" };
            if (request == null || request.Header == null || request.Header.ApplicationKey == null)
            {
                response.ErrorMessage = "Invalidate the request header";
                response.IsSuccess = false;
                return response;
            }

            var user = Provider.Users.RetrieveUser(request.Header.ApplicationKey.Value, request.UserName);
            if (user == null)
            {
                response.ErrorMessage = string.Format("Can not found user with ApplicationKey={0} in UserName={1}", request.Header.ApplicationKey, request.UserName);
                response.IsSuccess = false;
                return response;
            }

            UserRecord record = new UserRecord
            {
                ApplicationKey = new Guid(user.ApplicationKey),
                Password = user.Password,
                UserName = user.UserName,
                Active = user.IsActive,
                CreationDate = user.CreateDate,
                GroupIdentifier = user.GroupId,
                GroupName = user.Group == null ? null : user.Group.GroupNameEnglish
            };

            if (user.AccountInfo != null)
            {
                record.Email = user.AccountInfo.Email;
                record.FirstName = user.AccountInfo.FirstName;
                record.LastName = user.AccountInfo.LastName;
                record.Mobile = user.AccountInfo.MobilePin;
                record.ImageUrl = user.AccountInfo.ImageUrl;
                record.Birthday = user.AccountInfo.Birthday;
                record.Address = user.AccountInfo.Address;
                record.Gender = user.AccountInfo.Gender;
                //record.GroupIdentifier = user.GroupId;
            }
            response.Record = record;
            return response;
        }

        public UserRecord RetrieveUserByEmail(Guid applicationKey, string email)
        {
            throw new NotImplementedException();
            //RetrieveUserResponse response = new RetrieveUserResponse { IsSuccess = true, ErrorMessage = "" };
            //if (request == null || request.Header == null || request.Header.ApplicationKey == null)
            //{
            //    response.ErrorMessage = "Invalidate the request header";
            //    response.IsSuccess = false;
            //    return response;
            //}

            //var user = Provider.Users.RetrieveUserByEmail(request.Header.ApplicationKey.Value, request.Email);
            //if (user == null)
            //{
            //    response.ErrorMessage = string.Format("Can not found user with ApplicationKey={0} in UserName={1}", request.Header.ApplicationKey, request.UserName);
            //    response.IsSuccess = false;
            //    return response;
            //}

            //UserRecord record = new UserRecord
            //{
            //    ApplicationKey = new Guid(user.ApplicationKey),
            //    Password = user.Password,
            //    UserName = user.UserName
            //};

            //if (user.AccountInfo != null)
            //{
            //    record.Email = user.AccountInfo.Email;
            //    record.FirstName = user.AccountInfo.FirstName;
            //    record.LastName = user.AccountInfo.LastName;
            //    record.Mobile = user.AccountInfo.MobilePin;
            //    //record.GroupIdentifier = user.GroupId;
            //}
            //response.Record = record;
            //return response;
        }


        public RetrieveObjectsResponse RetrieveObjects(RetrieveObjectsRequest request)
        {
            return new RetrieveObjectsServiceCommand(Provider.Objects).Execute(request);
        }

        public List<RoleRecord> RetrieveRolesByUser(Guid applicationKey, string userName)
        {
            throw new NotImplementedException();
        }


        public RetrieveApplicationResponse RetrieveApplication(RetrieveApplicationRequest request)
        {
            bool isSuccess = true;
            string errorMessage = string.Empty;
            ApplicationRecord record = null;
            if (request == null) { errorMessage = "Invalidate request"; isSuccess = false; }
            else if (!request.Header.ApplicationKey.HasValue || request.Header.ApplicationKey == Guid.Empty) { errorMessage = "Invalidate request, Application key is invalidate."; isSuccess = false; }
            else
            {
                var applicationKey = request.Header.ApplicationKey;
                var application = Provider.Applications.RetrieveApplication(request.Header.ApplicationKey.Value);
                if (application != null)
                {
                    record = new ApplicationRecord
                    {
                        ApplicationKey = application.GuidKey,
                        CreationDate = application.CreatedUtc,
                        UpdateDate = application.ModifiedUtcDate,
                        Name = application.Name,
                        Description = application.Description,
                    };
                }
            }

            RetrieveApplicationResponse response = new RetrieveApplicationResponse
            {
                IsSuccess = isSuccess,
                ErrorMessage = errorMessage,
                Record = record
            };
            return response;
        }

        public SearchApplicationsResponse SearchApplications(SearchApplicationsRequest request)
        {
            return new SearchApplicationsServiceCommand(Provider.Applications).Execute(request);
        }

        public RetrieveGroupRolesResponse RetrieveGroupRoles(RetrieveGroupRolesRequest request)
        {
            return new RetrieveGroupRolesServiceCommand(Provider.GroupRole).Execute(request);
        }

        public RetrieveUserRolesResponse RetrieveUserRoles(RetrieveUserRolesRequest request)
        {
            return new RetrieveUserRolesServiceCommand(Provider.UserRole).Execute(request);
        }


        public ResponseRecord RegisterUser(RegisterUserRequest request)
        {
            bool isSuccess = true;
            string errorMessage = string.Empty;
            if (request == null || request.Record == null)
            {
                errorMessage = "Invalidate request";
                isSuccess = false;
            }
            else
            {
                var application = Provider.Applications.RetrieveApplication(request.Record.ApplicationKey);
                if (application == null)
                {
                    errorMessage = "Invalidate application request";
                    isSuccess = false;
                }
                else
                {
                    Account record = new Account
                    {
                        ApplicationKey = application.ApplicationKey,
                        Password = request.Record.Password,
                        UserName = request.Record.UserName,
                        CreateDate = DateTime.Now,
                        Active = BooleanString.TRUE,
                        AccountInfo = new AccountInfo
                        {
                            ApplicationKey = application.ApplicationKey,
                            UserName = request.Record.UserName,
                            Email = request.Record.Email,
                            FirstName = request.Record.FirstName,
                            LastName = request.Record.LastName,
                            MobilePin = request.Record.Mobile,
                            ImageUrl = request.Record.ImageUrl,
                            IsDeleted = BooleanString.FALSE,
                            IsAnonymous = BooleanString.FALSE,
                            IsApproved = BooleanString.TRUE,
                            IsLockedout = BooleanString.TRUE,
                            IsSuspended = BooleanString.FALSE,
                            CreateUtcDate = DateTime.UtcNow
                        }
                    };

                    var isAdded = Provider.Users.AddUser(record);
                    if (!isAdded)
                    {
                        errorMessage = "Can not insert supper admin user";
                        isSuccess = false;
                    }
                }
            }
            ResponseRecord response = new ResponseRecord
            {
                IsSuccess = isSuccess,
                ErrorMessage = errorMessage,
            };
            return response;
        }


        public ResponseRecord UpdateUser(UpdateUserRequest request)
        {
            return new UpdateUserServiceCommand(Provider.Users).Execute(request);
        }

        public SearchRolesResponse SearchRoles(SearchRolesRequest request)
        {
            return new SearchRolesServiceCommand(Provider.Roles).Execute(request);
        }

        public ResponseRecord AddRole(AddRoleRequest request)
        {
            return new AddRoleServiceCommand(Provider.Roles).Execute(request);
        }

        public ResponseRecord UpdateRole(UpdateRoleRequest request)
        {
            return new UpdateRoleServiceCommand(Provider.Roles).Execute(request);
        }

        public ResponseRecord DeleteRole(DeleteRoleRequest request)
        {
            return new DeleteRoleServiceCommand(Provider.Roles).Execute(request);
        }

        public ResponseRecord DeleteObject(DeleteObjectRequest request)
        {
            return new DeleteObjectServiceCommand(Provider.Objects).Execute(request);
        }

        public ResponseRecord UpdateObject(UpdateObjectRequest request)
        {
            return new UpdateObjectServiceCommand(Provider.Objects).Execute(request);
        }

        public ResponseRecord AddObject(AddObjectRequest request)
        {
            return new AddObjectServiceCommand(Provider.Objects).Execute(request);
        }

        public ResponseRecord DeleteGroup(DeleteGroupRequest request)
        {
            throw new NotImplementedException();
        }

        public ResponseRecord UpdateGroup(UpdateGroupRequest request)
        {
            return new UpdateGroupServiceCommand(Provider.Groups).Execute(request);
        }

        public ResponseRecord AddGroup(AddGroupRequest request)
        {
            return new AddGroupServiceCommand(Provider.Groups).Execute(request);
        }

        public RetrieveGroupsResponse RetrieveGroups(RetrieveGroupsRequest request)
        {
            return new RetrieveGroupsServiceCommand(Provider.Groups).Execute(request);
        }

        public RetrieveUsersResponse RetrieveUsers(RetrieveUsersRequest request)
        {
            return new RetrieveUsersServiceCommand(Provider.Users).Execute(request);
        }

        public ResponseRecord DeleteUserRoles(DeleteUserRolesRequest request)
        {
            return new DeleteUserRolesServiceCommand(Provider.UserRole).Execute(request);
        }

        public ResponseRecord DeleteGroupRoles(DeleteGroupRolesRequest request)
        {
            return new DeleteGroupRolesServiceCommand(Provider.GroupRole).Execute(request);
        }

        public ResponseRecord SaveGroupRoles(SaveGroupRolesRequest request)
        {
            return new SaveGroupRolesServiceCommand(Provider.GroupRole).Execute(request);
        }

        public ResponseRecord SaveUserRoles(SaveUserRolesRequest request)
        {
            return new SaveUserRolesServiceCommand(Provider.UserRole).Execute(request);
        }
    }
}